/*var functTestSets = ["Brinda_TS1", "Iteration 2"];
var regTestSets = ["Regression Old", "Cross Regression"];
var defectRelease = "Aug 2011";
var defectIteration = "Iteration 2";
var drawChart = true;
var displayTotals = true;*/

var functTestSets;
var regTestSets;
var defectRelease;
var defectIteration;
var drawChart;
var displayTotals;
var defectDetails = {};
var defectDetailsProcessingFlag = 0;
var defectDetailsProcessingFlagLimit = 1;
var blockedHeatColorMap = ['#FA5858', '#FA8258', '#FAAC58', '#F7D358'];
//?fts=Brinda_TS1,Iteration 2&rts=Regression Old,Cross Regression&defr=Aug 2011&defi=Iteration 2&dc=false&dt=false
	
function init() {	

	//var query = window.location.search;
	//var query = "?fts=Sprint 2 Round 1&rts=&defr=Release 2&defi=Iteration 2&dc=true&dt=true";
   //var query = "?fts=Round 1&rts=Regression&defr=Release 1&defi=&dc=true&dt=true";
	query = query.slice(1, query.length); //removing the ? at the beginning of the query parameter
  console.log("query is : " + query);
	query = query.split("&");
	$j.each(query, function(i,e){
		var keyValPair = e.replace(/%20/g, " ").split("=");
		var key = keyValPair[0];
		var val = keyValPair[1];
		switch(key){
			case "fts":
				functTestSets = val.split(",");
				break;
			case "rts":
				regTestSets = val.split(",");
				break;
			case "defr":
				defectRelease = val;
				break;
			case "defi":
				defectIteration = val;
				break;
			case "dc":
				drawChart = val == "true"?true:false;
				break;
			case "dt":
				displayTotals = val == "true"?true:false;
				break;
		}
	});
	if(hasValue(functTestSets)){
			getTestIDs(functTestSets, 'functional');
			defectDetailsProcessingFlagLimit += 1;
		}
		else
			$j('#fouter').hide();
	if(hasValue(regTestSets)){
			getTestIDs(regTestSets, 'regression');
			defectDetailsProcessingFlagLimit += 1;
		}
		else
			$j('#router').hide();
	if(defectRelease && defectIteration)
		getDefects(defectRelease, defectIteration);

}

//for a given test set, find all the objectids of associated test cases
function getTestIDs(ts, testType){

  console.log("In getTestIDs " + ts + ";" + testType);
	
	//append each element of ts array to look like a query 'name = "ts_name"'
	var queries = $j.map(ts, function(e,i){
		return 'name = "'+e+'"';
	});
	//constructing rally query format
	var queryObj = rally.sdk.util.Query.or(queries);

	var rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__', 
															'__PROJECT_OID__',  
															'__PROJECT_SCOPING_UP__', 
															'__PROJECT_SCOPING_DOWN__');
	var queryConfig = [];
	queryConfig[0] = {  
                key: 'ts',  
                type: 'testset',
				query: queryObj,
                fetch: 'Name,TestCases'
            };
	rallyDataSource.findAll(queryConfig, function(results){
		processTestIDs(results, testType);
	});
}

function processTestIDs(results, testType){

  console.log("In processTestIDs" + results + ";" + testType);
	var resultDataChild = new Array();
	
	$j.each(results.ts, function(i,e){
		var testsetName = e.Name;
		$j.each(e.TestCases, function(ii,ee){
			var reference = ee._ref;
			reference = getIDFromURL(reference); //extracting the object id from the _ref url
			resultDataChild[reference] = {'testset' : testsetName};
		});
	});
	getFolderNames(resultDataChild, testType);
}

function getFolderNames(resultDataChild, testType){

  console.log("In getFolderNames " + ts + ";" + testType);
	var testIDArr = new Array();
	for(testID in resultDataChild){
		testIDArr.push(testID);
	}
	var queries = $j.map(testIDArr, function(e,i){
		return 'objectid = ' + e;
	});
	/*var queryObj = rally.sdk.util.Query.or(queries);
	var rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__', 
															'__PROJECT_OID__',  
															'__PROJECT_SCOPING_UP__', 
															'__PROJECT_SCOPING_DOWN__');
	var queryConfig = [];
	queryConfig[0] = {  
                key: 'tfs',  
                type: 'testcase',
				query: queryObj,
                fetch: 'objectid,testfolder'
            };
	rallyDataSource.findAll(queryConfig, function(results){
		processFolderNames(results, resultDataChild, testType);
	});*/
	
	throttleQueries(queries, 30, 
					function(inp){
						return rally.sdk.util.Query.or(inp);
					},
					function(inp){
						var queryConfig = [];
						queryConfig[0] = {  
									key: 'tfs',  
									type: 'testcase',
									query: inp,
									fetch: 'objectid,testfolder'
								};
						return queryConfig;
					},
					function(inp){
						processFolderNames(inp, resultDataChild, testType);
					});
}

function processFolderNames(results, resultDataChild, testType){
	$j.each(results.tfs, function(i,e){
		var testOID = e.ObjectID;
		var testFolderName = e.TestFolder._refObjectName;
		var testobj = resultDataChild[testOID];
		testobj.testfolder = testFolderName;
	});
	getTestResults(resultDataChild, testType);
}

function getTestResults(resultDataChild, testType){
	var queries = [];
	for(testID in resultDataChild){
		var query1 = new rally.sdk.util.Query('testcase.objectid = '+testID);
		var query2 = query1.and('testset.name = "'+resultDataChild[testID].testset+'"');
		queries.push(query2);
	}
	
	throttleQueries(queries, 20, 
		function(inp){
			var queryObj = inp[0];
			$j.each(inp.slice(1), function(i,e){
				queryObj = queryObj.or(e);
			});
			return queryObj;
		}, 
		function(inp){
			var queryConfig = [];
			queryConfig[0] = {  
						key: 'tvr',  
						type: 'testcaseresult',
						query: inp,
						fetch: 'verdict,date,testcase,Notes',
						order: 'date desc'
					};
			return queryConfig;
		}, 
		function(inp){
			processTestResults(inp, resultDataChild, testType);
		}
	);
}


function processTestResults(results, resultDataChild, testType){
	
	//regexp to check for blocked test case string
	var re = /(Blocked due to )(DE[0-9]+)/gi; //... Blocked due to DE666 ...
	
	//grouping all test results based on test id by processing the results object. RALLY SORTED approach
	var resGroupByTestID = new Array();
	$j.each(results.tvr, function(i, e){
		var testID = getIDFromURL(e.TestCase._ref);
		var verdict = e.Verdict;
		var VDObj = resGroupByTestID[testID];
		if(!VDObj){
				resGroupByTestID[testID] = verdict;
				//checking whether the test case is blocked due to any test case
				var notesText = e.Notes;
				if (notesText && notesText != ""){
					var arr = re.exec(notesText);
					if(arr){
						upsert(defectDetails, "B-"+arr[2], function(ctr){
							return ctr ? ctr + 1 : 1;
						});
					}
				}
			}
	});
	for(testID in resGroupByTestID){
		var resObj = resultDataChild[testID];
		resObj.verdict = resGroupByTestID[testID];
	}
	summarizeAndShow(resultDataChild, testType);
	displayDefectDetails();
}

function summarizeAndShow(resultDataChild, testType){
	var s = new Summarizer();
	for(itemKey in resultDataChild){
		var item = resultDataChild[itemKey];
		//console.log("ID is "+itemKey);
		s.increment(item.testfolder, item.verdict ? item.verdict :'Unexecuted', function(val){
																						if(val)
																							return val += 1;
																						else
																							return 1;
		});
	}
	displaySummary(s, testType, 0);
}

function getDefects(release, iteration){
	var rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__', 
															'__PROJECT_OID__',  
															'__PROJECT_SCOPING_UP__', 
															'__PROJECT_SCOPING_DOWN__');
	var queryConfig = [];
	var queryStr = '((Release.Name = "'+release+'") AND (Iteration.Name = "'+iteration+'"))';
	queryConfig[0] = {  
                key: 'd',  
                type: 'defect',
				query: queryStr,
                fetch: 'ObjectID,State,TestCase,FormattedID,TestCase'
				//fetch: 'objectid,state,testcase' //Rally Bug. To be reported!
            };
	queryConfig[1] = {  
                key: 'tfs',  
                placeholder: '${d.TestCase.TestFolder.Name}'
            };
	rallyDataSource.findAll(queryConfig, processDefects);
}

function processDefects(results){
	//console.log(results);
	var s = new Summarizer();
	var defectsArr = results.d;
	var testFoldersArr = results.tfs;
	$j.each(defectsArr, function(i, e){
		var defectID = e.ObjectID;
		var status = e.State;
		var testFolder = testFoldersArr[i];
		testFolder = (testFolder && testFolder != "null") ? testFolder : "Undefined";
		s.increment(testFolder, status, function(val){
											if(val)
												return val += 1;
											else
												return 1;
		});
		
		if (status != "Closed"){
			//console.log('Test Case for '+ e.FormattedID + ' is ');
			//console.log(e.TestCase);
			var blockedCount = e.TestCase ? 1 : 0;
			defectDetails[e.FormattedID] = {'status': status, 'testFolder': testFolder, 'blockedCount': blockedCount, 'oid':defectID};
		}
	});
	displaySummary(s, 'defects', 0);
	displayDefectDetails();
}

function displaySummary(s, divID, defaultVal){
	var tableCols = $j.map(s.getColumns(), function(e, i){
		var headerVal = (e == "rowheader")? ' ' : e;
		if (headerVal == " ")
			return {'key': e, 'header': headerVal, 'width': 200};
		else
			return {'key': e, 'header': headerVal, 'width': 80};
	});
	var tableConfig = {'columns': tableCols, 'items': s.getItems(defaultVal)};
	var table = new rally.sdk.ui.Table(tableConfig);
	table.display($j('#'+divID).get(0));
	
	if(displayTotals){
		showTotals(table, divID);
	}
	if(drawChart && (divID != 'defects') && (divID != 'blockedmap')){ //change this code to not-in type of code
		renderChart(table, divID);
	}
}

function showTotals(tableObj, divID){
}
function renderChart(tableObj, divID){

	var data = new google.visualization.DataTable();
	data.addColumn('string', 'Name');
	
	//Going to add the test status column names to the data obj
	//console.log('debug 1');
	var colNames = $j('#'+divID+' th div').map(function(i, e){
		var colName = $j(e).text();
		if(colName != " "){
			data.addColumn('number', colName); //adding column name to the data obj
			return colName; //need to capture this in an array to setup colors, later!
		}
	}).get();
	//console.log(colNames);
	var rowData = $j('#'+divID+' tr').map(function(index, elem){ //for each row in the table
		if(index != 0){ //ignore the first row of the table, since 
			var cells = $j(elem).children('td').map(function(inIndex, inElem){//for each cell in a row
				if(inIndex == 0)
					return $j(inElem).text();
				else
					return parseInt($j(inElem).text());
			}).get();
			var sum = 0;
			$j.each(cells, function(i,e){
				if(i != 0)
					sum += e;
			});
			cells = $j.map(cells, function(e, i){
				return (i == 0)? e :Math.round(e*100/sum);
			});
			return [cells];
		}
	}).get();

	var colorNames = $j.map(colNames, function(e,i){
		switch (e){
			case "Unexecuted":
				return "#BFBFBA";
			case "Blocked":
				return "#A32448";
			case "Error":
				return "#92BEDE";
			case "Fail":
				return "#F77979";
			case "Inconclusive":
				return "#F5CD5F";
			case "Pass":
				return "#B6F5A2";
		}
	});
	
	data.addRows(rowData);
	new google.visualization.ColumnChart(document.getElementById(divID+'chart')).
      draw(data,
           {width:800, height:300,
            isStacked: true,
            enableInteractivity: false,
			chartArea: {left:25,top:10, width:"50%",height:"75%"},
			//hAxis: {slantedText: true, slantedTextAngle: 15},
			vAxis: {viewWindowMode: "explicit", viewWindow: {max: 100}},
            colors:colorNames}
      );
}

function displayDefectDetails(){
		
		
		defectDetailsProcessingFlag += 1;
		//guard condition to check whether it's ready to process defects
		if (defectDetailsProcessingFlag != defectDetailsProcessingFlagLimit)
			return -1;
		
		//taking all the B- counts from testcaseresult descriptions and adding to blocked count of respective defect
		for(key in defectDetails){
			if (key.indexOf('B-') == 0){
				var defectID = key.substr(2);
				var defectCount = defectDetails[key];
				delete defectDetails[key];
				upsert(defectDetails, defectID, function(keyval){
					if(keyval){
						keyval.blockedCount += defectCount;
						return keyval;
					}	
					return null;
				});
			}
		}
		
		//var bhcmLen = blockedHeatColorMap.length;
		//defectDetails[e.FormattedID] = {'status': status, 'testFolder': testFolder, 'blockedCount': blockedCount, 'oid':defectID};
		console.log(rally);
		var s = new Summarizer();
		for(key in defectDetails){
			var dObj = defectDetails[key];
			var anchorText = 	"<a style='background-color:#FA5858' href='"
								//+ rally.sdk.util.Navigation.createRallyDetailUrl("/defect/"+dObj.oid)
								+ "/defect/"+dObj.oid
								+"'>"
								+key
								+" ("+dObj.blockedCount+")</a>"
			s.increment(dObj.testFolder, dObj.status, function(inVal){
															if (inVal)
																return inVal += ", <br/>" + anchorText;
															else
																return anchorText;
			});
		}
		displaySummary(s, 'blockedmap', "-");
}